using System;
using System.Reflection;
using UnityEngine;

namespace CNGraphi.U6URP
{
    /// <summary>
    /// 反射工具
    /// <para>作者：CN.Graphi</para>
    /// </summary>
    public class ReflectUtils
    {
        /// <summary>
        /// 反射函数
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="typ">类的类型</param>
        /// <param name="methodName">函数名</param>
        /// <param name="args">函数参数</param>
        /// <returns></returns>
        static public T CallbackMethod<T>(Type typ, string methodName, params object[] args)
        {
            T defaultValue = default(T);
            Type[] argTypes = new Type[args.Length];
            for (int i = 0, count = args.Length; i < count; ++i)
            {
                argTypes[i] = null != args[i] ? args[i].GetType() : null;
            }
            MethodInfo method = typ.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, argTypes, null);
            if (null == method)
            {
                Debug.LogError(string.Format("method {0} does not exist!", methodName));
                return defaultValue;
            }
            object result = method.Invoke(null, args);
            if (null == result)
                return defaultValue;
            if (!(result is T))
            {
                Debug.LogError(string.Format("method {0} cast failed!", methodName));
                return defaultValue;
            }
            return (T)result;
        }

        /// <summary>
        /// 反射函数
        /// </summary>
        /// <param name="typ">类的类型</param>
        /// <param name="methodName">函数名</param>
        /// <param name="args">参数</param>
        static public void CallMethod(Type typ, string methodName, params object[] args)
        {
            Type[] argTypes = new Type[args.Length];
            for (int i = 0, count = args.Length; i < count; ++i)
            {
                argTypes[i] = null != args[i] ? args[i].GetType() : null;
            }
            MethodInfo method = typ.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, argTypes, null);
            if (null == method)
            {
                Debug.LogError(string.Format("method {0} does not exist!", methodName));
                return;
            }
            method.Invoke(null, args);
        }

    }
}